package World.Module.ObjectPool;

import MObject.IPool;
import World.ISingletonAwake;
import World.Singleton;

import java.util.SortedMap;
import java.util.concurrent.ConcurrentHashMap;

public class ObjectPool extends Singleton implements ISingletonAwake {

    private ConcurrentHashMap<Class<?>, Pool> objectPool;

    private final static int DefaultCapacity = 1000;

    @Override
    public void Awake() {
        synchronized (this)
        {
            objectPool = new ConcurrentHashMap<>();
        }
    }

    public <T> T Fetch(Class<?> type)
    {
        Pool pool = GetPool(type);
        Object object = pool.Get();
        if(object instanceof IPool)
        {
            ((IPool) object).SetIsFromPool(true);
        }
        return (T)object;
    }

    public void Recycle(Object object)
    {
        if(object instanceof IPool)
        {
            IPool pool = (IPool) object;
            if(!pool.GetIsFromPool())
            {
                return;
            }
            pool.SetIsFromPool(false);
        }
        GetPool(object.getClass()).Return(object);
    }

    private Pool GetPool(Class<?> type)
    {
        try {
            return this.objectPool.get(type);
        }catch (NullPointerException e)
        {
            Pool pool = new Pool(type, DefaultCapacity);
            this.objectPool.put(type, pool);
            return pool;
        }
    }
}
